{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Predições privadas com Syft Keras"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Passo 1: Treinamento Público\n",
    "\n",
    "Bem-vindo a este tutorial! Nos exemplos seguintes, você aprenderá como fornecer predições privadas. Por predições privadas, queremos dizer que os dados são constantemente encriptados ao longo de todo o processo. Em nenhum momento o usuário partilha os dados brutos, apenas dados encriptados (ou seja, compartilhamento secreto). A fim de fornecer essas predições privadas, a Syft Keras usa uma biblioteca chamada [TF Encrypted](https://github.com/tf-encrypted/tf-encrypted) por baixo dos panos. TF Encrypted combina criptografia de ponta (i.e cutting-edge cryptographic) e técnicas de aprendizagem de máquina, mas você não precisa se preocupar com isso e pode se concentrar na sua aplicação de aprendizagem de máquina.\n",
    "\n",
    "Você pode começar a realizar predições privadas com apenas três passos:\n",
    "- **Passo 1**: Treine seu modelo com o Keras normalmente.\n",
    "- **Passo 2**: Proteja e disponibilize seu modelo de aprendizagem de máquina (server).\n",
    "- **Passo 3**: Consulte o modelo seguro para receber predições privadas. \n",
    "\n",
    "Muito bem, vamos passar por estes três passos para que possa que você possa implementar serviços de aprendizagem de máquinas impactantes sem sacrificar a privacidade do usuário ou a segurança do modelo.\n",
    "\n",
    "Autores:\n",
    "- Jason Mancuso - Twitter: [@jvmancuso](https://twitter.com/jvmancuso)\n",
    "- Yann Dupis - Twitter: [@YannDupis](https://twitter.com/YannDupis)\n",
    "- Morten Dahl - Twitter: [@mortendahlcs](https://github.com/mortendahlcs)\n",
    "\n",
    "Em nome de:\n",
    "- Dropout Labs - Twitter: [@dropoutlabs](https://twitter.com/dropoutlabs)\n",
    "- TF Encrypted - Twitter: [@tf_encrypted](https://twitter.com/tf_encrypted)\n",
    "\n",
    "Tradução:\n",
    "- Marcus Costa - Twitter: [@marcustpv](https://twitter.com/marcustpv)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Treine seu modelo com o Keras"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para utilizar técnicas de privacidade em aprendizagem de máquina nos seus projetos, você não deve ter que aprender um novo _framework_ de aprendizagem de máquina. Se você tem conhecimentos básicos de [Keras](https://keras.io/), você pode começar a usar estas técnicas com Syft Keras. Se você nunca usou o Keras antes, você pode aprender um pouco mais sobre ele através da [documentação do Keras](https://keras.io). \n",
    "\n",
    "Antes de servir predições privadas, o primeiro passo é treinar o seu modelo com Keras como você faria normalmente. Como exemplo, vamos treinar um modelo para classificar dígitos escritos à mão. Para treinar este modelo vamos usar o conjunto de dados [MNIST](http://yann.lecun.com/exdb/mnist/).\n",
    "\n",
    "Pegamos [este exemplo](https://github.com/keras-team/keras/blob/master/examples/mnist_cnn.py) emprestado do repositório de referência do Keras. Para treinar o seu modelo de classificação, basta executar a célula abaixo."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "import tensorflow.keras as keras\n",
    "from tensorflow.keras.datasets import mnist\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Dense, Dropout, Flatten\n",
    "from tensorflow.keras.layers import Conv2D, AveragePooling2D\n",
    "from tensorflow.keras.layers import Activation\n",
    "\n",
    "batch_size = 128\n",
    "num_classes = 10\n",
    "epochs = 2\n",
    "\n",
    "# dimensoes da imagem de entrada\n",
    "img_rows, img_cols = 28, 28\n",
    "\n",
    "# os dados, divididos em treino e teste\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n",
    "x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n",
    "input_shape = (img_rows, img_cols, 1)\n",
    "\n",
    "x_train = x_train.astype('float32')\n",
    "x_test = x_test.astype('float32')\n",
    "x_train /= 255\n",
    "x_test /= 255\n",
    "print('x_train shape:', x_train.shape)\n",
    "print(x_train.shape[0], 'train samples')\n",
    "print(x_test.shape[0], 'test samples')\n",
    "\n",
    "# convertendo os vetores de classes em matrizes de classses binarias.\n",
    "y_train = keras.utils.to_categorical(y_train, num_classes)\n",
    "y_test = keras.utils.to_categorical(y_test, num_classes)\n",
    "\n",
    "model = Sequential()\n",
    "\n",
    "model.add(Conv2D(10, (3, 3), input_shape=input_shape))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(32, (3, 3)))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(64, (3, 3)))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Flatten())\n",
    "model.add(Dense(num_classes, activation='softmax'))\n",
    "\n",
    "model.compile(loss=keras.losses.categorical_crossentropy,\n",
    "              optimizer=keras.optimizers.Adam(),\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "model.fit(x_train, y_train,\n",
    "          batch_size=batch_size,\n",
    "          epochs=epochs,\n",
    "          verbose=1,\n",
    "          validation_data=(x_test, y_test))\n",
    "score = model.evaluate(x_test, y_test, verbose=0)\n",
    "print('Test loss:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Salve os pesos do seu modelo para futuras predições privadas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ótimo! O seu modelo está treinado. Vamos salvar os pesos do modelo com a chamada `model.save()`. No próximo \n",
    "*notebook*, vamos carregar estes pesos no Syft Keras para começar a servir predições privadas. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.save('short-conv-mnist.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
